package com.tevintao.marketingsystem.services;

import android.graphics.Rect;
import android.os.SystemClock;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.ListView;

import com.tevintao.marketingsystem.log.LogManager;
import com.tevintao.marketingsystem.tool.ClassTool;
import com.tevintao.marketingsystem.xposted.HookAudioRecord;
import com.tevintao.marketingsystem.xposted.HookWindowManagerGlobal;

import java.util.Random;

public class ViewOperation {


    public static boolean clickView(final View v) {
        if (null == v) {
            return false;
        }
        v.post(new Runnable() {
            @Override
            public void run() {
                boolean clickSuccess = setSimulateViewClick(v);
                LogManager.getInstance().logInfo("clickView view id = " + v.getId() + " state = " + clickSuccess);

            }
        });
        return true;
    }

    public static boolean doubleClickView(final View v) {
        if (null == v) {
            return false;
        }
        v.post(new Runnable() {
            @Override
            public void run() {
                boolean clickSuccess = setSimulateViewClick(v);
                LogManager.getInstance().logInfo("clickView view id = " + v.getId() + " clickSuccess = " + clickSuccess);
                boolean clickSuccess2 = setSimulateViewClick(v);
                LogManager.getInstance().logInfo("clickView view id = " + v.getId() + " clickSuccess2 = " + clickSuccess2);

            }
        });
        return true;
    }

    public static boolean doClickListener(final View v) {
        if (null == v) {
            return false;
        }
        v.post(new Runnable() {
            @Override
            public void run() {
                if (v.hasOnClickListeners()) {
                    View.OnClickListener clickListener = ClassTool.getViewOnClickListener(v);
                    if (null != clickListener) {
                        clickListener.onClick(v);
                    } else {
                        LogManager.getInstance().logError("null != clickListener 获取点击事件失败");
                    }
                } else {
                    LogManager.getInstance().logError("doClickListener v no click listener");
                }
            }
        });

        return true;
    }

    public static boolean setText(final View v, final String content) {
        if (null == v || !(v instanceof EditText)) {
            return false;
        }
        v.post(new Runnable() {
            @Override
            public void run() {
                ((EditText) v).setText(content);
            }
        });
        return true;
    }

    public static boolean moveListPosition(final View v, final int position) {
        if (null == v || !(v instanceof ListView)) {
            return false;
        }
        v.post(new Runnable() {
            @Override
            public void run() {
                ListView listView = (ListView) v;
                listView.setSelection(position);

            }
        });
        return true;
    }


    public static boolean setSimulateViewClick(View view) {
        Rect r = new Rect();
        view.getGlobalVisibleRect(r);

        int x;
        int y;
        if (r.top == 0 && r.bottom == 0 && r.left == 0 && r.right == 0) {
            int[] pxy = new int[2];
            view.getLocationOnScreen(pxy);
            LogManager.getInstance().logInfo("getLocationOnScreen  x" + pxy[0] + " y " + pxy[1]);
            x = pxy[0] + 3;
            y = pxy[1] + 3;
        } else {
            x = r.left + view.getWidth() / 2;
            y = r.top + view.getHeight() / 2;
        }

        long downTime = SystemClock.uptimeMillis();
        final MotionEvent downEvent = MotionEvent.obtain(downTime, downTime,
                MotionEvent.ACTION_DOWN, x, y, 0);
        downTime += 1000;
        final MotionEvent upEvent = MotionEvent.obtain(downTime, downTime,
                MotionEvent.ACTION_UP, x, y, 0);
        View topView = HookWindowManagerGlobal.getInstance().getTopView();
        if (null == topView) {
            LogManager.getInstance().logInfo("setSimulateViewClick get topview is null");
            return false;
        } else {
            LogManager.getInstance().logInfo("setSimulateViewClick topView = " + topView.getContext().toString());
        }

        boolean down = topView.dispatchTouchEvent(downEvent);
        boolean up = topView.dispatchTouchEvent(upEvent);

        downEvent.recycle();
        upEvent.recycle();

        LogManager.getInstance().logError("down = " + down + " up = " + up + "  x  =  " + x + "  y  " + y);
        return down && up;
    }

    public static boolean clickViewOffset(final View view, final int offsetX, final int offsetY) {
        if (null == view) {
            return false;
        }

        view.post(new Runnable() {
            @Override
            public void run() {
                boolean clickViewOffset = setSimulateViewClickPosition(view, offsetX, offsetY);
                LogManager.getInstance().logInfo("clickViewOffset = " + clickViewOffset);
            }
        });
        return true;
    }

    public static boolean setSimulateViewClickPosition(View view, int offsetX, int offsetY) {
        Rect r = new Rect();
        view.getGlobalVisibleRect(r);
        int x = r.left + offsetX;
        int y = r.top + offsetY;

        long downTime = SystemClock.uptimeMillis();
        final MotionEvent downEvent = MotionEvent.obtain(downTime, downTime,
                MotionEvent.ACTION_DOWN, x, y, 0);
        downTime += 1000;
        final MotionEvent upEvent = MotionEvent.obtain(downTime, downTime,
                MotionEvent.ACTION_UP, x, y, 0);
        View topView = HookWindowManagerGlobal.getInstance().getTopView();
        if (null == topView) {
            LogManager.getInstance().logInfo("setSimulateViewClick get topview is null");
            return false;
        }

        boolean down = topView.dispatchTouchEvent(downEvent);
        boolean up = topView.dispatchTouchEvent(upEvent);

        downEvent.recycle();
        upEvent.recycle();

        return down && up;
    }

    public static boolean setChecked(final CheckBox checkBox, final boolean checked) {
        if (null == checkBox) {
            return false;
        }
        checkBox.post(new Runnable() {
            @Override
            public void run() {
                checkBox.setChecked(checked);
            }
        });
        return true;
    }


    public static boolean moveList2Header(final ListView listView) {
        if (null == listView) {
            return false;
        }
        listView.post(new Runnable() {
            @Override
            public void run() {
                listView.setSelectionAfterHeaderView();
            }
        });
        return true;
    }

    private static final int randomTimeBase = 55;
    //    private static final int randomTimeBase = 25;
    private static final int randomTimeStep = 5;
    private static Random random = new Random();

    public static boolean moveHalfScreenUp(View view) {
        Rect r = new Rect();
        view.getGlobalVisibleRect(r);

        int middleX;
        int middleY;
        if (r.top == 0 && r.bottom == 0 && r.left == 0 && r.right == 0) {
            int[] pxy = new int[2];
            view.getLocationOnScreen(pxy);
            Log.i("ttw", "getLocationOnScreen  x" + pxy[0] + " y " + pxy[1]);
            middleX = pxy[0];
            middleY = pxy[1];
        } else {
            middleX = r.left + view.getWidth() / 2;
            middleY = r.top + view.getHeight() / 2;
        }

        int height = view.getHeight();

        long downTime = SystemClock.uptimeMillis();
        long eventTime = downTime;
        MotionEvent downEvent = MotionEvent.obtain(downTime, downTime,
                MotionEvent.ACTION_DOWN, middleX, middleY - height / 3 + random.nextInt(10), 0);

        eventTime += randomTimeBase + random.nextInt(randomTimeStep);
        MotionEvent moveEvent_1 = MotionEvent.obtain(downTime, eventTime,
                MotionEvent.ACTION_MOVE, middleX, middleY - height / 4 + random.nextInt(10), 0);

        eventTime += randomTimeBase + random.nextInt(randomTimeStep);
        MotionEvent moveEvent_2 = MotionEvent.obtain(downTime, eventTime,
                MotionEvent.ACTION_MOVE, middleX, middleY - height / 5 + random.nextInt(10), 0);

        eventTime += randomTimeBase + random.nextInt(randomTimeStep);
        MotionEvent moveEvent_3 = MotionEvent.obtain(downTime, eventTime,
                MotionEvent.ACTION_MOVE, middleX, middleY, 0);

        eventTime += randomTimeBase + random.nextInt(randomTimeStep);
        MotionEvent moveEvent1 = MotionEvent.obtain(downTime, eventTime,
                MotionEvent.ACTION_MOVE, middleX, middleY + height / 5 + random.nextInt(10), 0);


        eventTime += randomTimeBase + random.nextInt(randomTimeStep);
        MotionEvent moveEvent2 = MotionEvent.obtain(downTime, eventTime,
                MotionEvent.ACTION_MOVE, middleX, middleY + height / 4 + random.nextInt(10), 0);
        eventTime += randomTimeBase + random.nextInt(randomTimeStep);
        MotionEvent moveEvent3 = MotionEvent.obtain(downTime, eventTime,
                MotionEvent.ACTION_MOVE, middleX, middleY + height / 4 + 10 + random.nextInt(10), 0);
        eventTime += randomTimeBase + random.nextInt(randomTimeStep);
        MotionEvent moveEvent4 = MotionEvent.obtain(downTime, eventTime,
                MotionEvent.ACTION_MOVE, middleX, middleY + height / 4 + 20 + random.nextInt(10), 0);
        eventTime += randomTimeBase + random.nextInt(randomTimeStep);
        MotionEvent moveEvent5 = MotionEvent.obtain(downTime, eventTime,
                MotionEvent.ACTION_MOVE, middleX, middleY + height / 4 + 30 + random.nextInt(10), 0);


        eventTime += randomTimeBase + random.nextInt(randomTimeStep);
        MotionEvent upEvent = MotionEvent.obtain(downTime, eventTime,
                MotionEvent.ACTION_UP, middleX, middleY + height / 3 + random.nextInt(10), 0);

        View topView = HookWindowManagerGlobal.getInstance().getTopView();
        if (null == topView) {
            Log.i("ttw", "setSimulateViewClick get topview is null");
            return false;
        }

        boolean down = topView.dispatchTouchEvent(downEvent);

        boolean move_1 = topView.dispatchTouchEvent(moveEvent_1);
        boolean move_2 = topView.dispatchTouchEvent(moveEvent_2);
        boolean move_3 = topView.dispatchTouchEvent(moveEvent_3);


        boolean move1 = topView.dispatchTouchEvent(moveEvent1);
        boolean move2 = topView.dispatchTouchEvent(moveEvent2);
        boolean move3 = topView.dispatchTouchEvent(moveEvent3);
        boolean move4 = topView.dispatchTouchEvent(moveEvent4);
        boolean move5 = topView.dispatchTouchEvent(moveEvent5);
//
        boolean up = topView.dispatchTouchEvent(upEvent);

        downEvent.recycle();
        moveEvent_1.recycle();
        moveEvent_2.recycle();
        moveEvent_3.recycle();

        moveEvent1.recycle();
        moveEvent2.recycle();

        moveEvent3.recycle();
        moveEvent4.recycle();
        moveEvent5.recycle();
        upEvent.recycle();


        Log.i("ttw", "down = " + down + " move_1 = " + move_1 + " move_2 = " + move_2 + " move_3 = " + move_3 + " move1 = " + move1 + " move2 = " + move2 + " move3 = " + move3 + " move4 = " + move4 + " move5 = " + move5 + " up = " + up);
        return down && up;
    }


    public static boolean moveHalfScreenNext(View view) {
        Rect r = new Rect();
        view.getGlobalVisibleRect(r);

        int middleX;
        int middleY;
        if (r.top == 0 && r.bottom == 0 && r.left == 0 && r.right == 0) {
            int[] pxy = new int[2];
            view.getLocationOnScreen(pxy);
            Log.i("ttw", "getLocationOnScreen  x" + pxy[0] + " y " + pxy[1]);
            middleX = pxy[0];
            middleY = pxy[1];
        } else {
            middleX = r.left + view.getWidth() / 2;
            middleY = r.top + view.getHeight() / 2;
        }

        int height = view.getHeight();

        long downTime = SystemClock.uptimeMillis();
        long eventTime = downTime;
        MotionEvent downEvent = MotionEvent.obtain(downTime, downTime,
                MotionEvent.ACTION_DOWN, middleX, middleY + height / 3 + random.nextInt(10), 0);

        eventTime += randomTimeBase + random.nextInt(randomTimeStep);
        MotionEvent moveEvent_1 = MotionEvent.obtain(downTime, eventTime,
                MotionEvent.ACTION_MOVE, middleX, middleY + height / 4 + random.nextInt(10), 0);

        eventTime += randomTimeBase + random.nextInt(randomTimeStep);
        MotionEvent moveEvent_2 = MotionEvent.obtain(downTime, eventTime,
                MotionEvent.ACTION_MOVE, middleX, middleY + height / 5 + random.nextInt(10), 0);

        eventTime += randomTimeBase + random.nextInt(randomTimeStep);
        MotionEvent moveEvent_3 = MotionEvent.obtain(downTime, eventTime,
                MotionEvent.ACTION_MOVE, middleX, middleY, 0);

        eventTime += randomTimeBase + random.nextInt(randomTimeStep);
        MotionEvent moveEvent1 = MotionEvent.obtain(downTime, eventTime,
                MotionEvent.ACTION_MOVE, middleX, middleY - height / 5 + random.nextInt(10), 0);
        eventTime += randomTimeBase + random.nextInt(randomTimeStep);
        MotionEvent moveEvent2 = MotionEvent.obtain(downTime, eventTime,
                MotionEvent.ACTION_MOVE, middleX, middleY - height / 4 + random.nextInt(10), 0);
        eventTime += randomTimeBase + random.nextInt(randomTimeStep);
        MotionEvent upEvent = MotionEvent.obtain(downTime, eventTime,
                MotionEvent.ACTION_UP, middleX, middleY - height / 3 + random.nextInt(10), 0);

        View topView = HookWindowManagerGlobal.getInstance().getTopView();
        if (null == topView) {
            Log.i("ttw", "setSimulateViewClick get topview is null");
            return false;
        }

        boolean down = topView.dispatchTouchEvent(downEvent);

        boolean move_1 = topView.dispatchTouchEvent(moveEvent_1);
        boolean move_2 = topView.dispatchTouchEvent(moveEvent_2);
        boolean move_3 = topView.dispatchTouchEvent(moveEvent_3);


        boolean move1 = topView.dispatchTouchEvent(moveEvent1);
        boolean move2 = topView.dispatchTouchEvent(moveEvent2);
//        boolean move3 = topView.dispatchTouchEvent(moveEvent3);

        boolean up = topView.dispatchTouchEvent(upEvent);

        downEvent.recycle();
        moveEvent_1.recycle();
        moveEvent_2.recycle();
        moveEvent_3.recycle();

        moveEvent1.recycle();
        moveEvent2.recycle();
//        moveEvent3.recycle();
        upEvent.recycle();

        Log.i("ttw", "down = " + down + " move_1 = " + move_1 + " move_2 = " + move_2 + " move_3 = " + move_3 + " move1 = " + move1 + " move2 = " + move2 + " move3 = " + " up = " + up);
        return down && up;
    }


    public static boolean PressDownView(final View v) {
        if (null == v) {
            return false;
        }
        v.post(new Runnable() {
            @Override
            public void run() {
                boolean clickSuccess = setSimulateViewPressDown(v);
                LogManager.getInstance().logInfo("clickView view id = " + v.getId() + " state = " + clickSuccess);
                AudioFinishPressUp(v);
            }
        });
        return true;
    }

    private static checkAudioStopRunnable stopAudio = null;

    public static boolean AudioFinishPressUp(final View v) {
        if (null == v) {
            return false;
        }
        if (null == stopAudio) {
            stopAudio = new checkAudioStopRunnable(v);
        }
        v.postDelayed(stopAudio, 2000);
        return true;
    }

    static class checkAudioStopRunnable implements Runnable {

        public checkAudioStopRunnable(View upView) {
            this.upView = upView;
        }

        View upView;

        @Override
        public void run() {
            upView.removeCallbacks(stopAudio);
            LogManager.getInstance().logInfo("checkAudioStopRunnable HookAudioRecord.getAudioState() = " + HookAudioRecord.getAudioState() + "   process name = " + MockServices.getProcessName() + " HookAudioRecord.class.hashCode() =  " + HookAudioRecord.class.hashCode() + " getClassLoader().hashCode() = " + HookAudioRecord.class.getClassLoader().hashCode());
            if (HookAudioRecord.getAudioState()) {
                LogManager.getInstance().logInfo("正在输入语音");
                upView.postDelayed(stopAudio, 500);
            } else {
                LogManager.getInstance().logInfo("输入语音输入完毕");
                TaskLogicService.sendKeyEvent(upView.getContext(), TaskLogicService.INPUT_TYPE_BACK);
//                setSimulateViewPressUp(upView);
//                clickView(upView);
                stopAudio = null;
            }

        }
    }


    private static long pressDownTime = 0;

    public static boolean setSimulateViewPressDown(View view) {
        Rect r = new Rect();
        view.getGlobalVisibleRect(r);
        int x;
        int y;
        if (r.top == 0 && r.bottom == 0 && r.left == 0 && r.right == 0) {
            int[] pxy = new int[2];
            view.getLocationOnScreen(pxy);
            LogManager.getInstance().logInfo("getLocationOnScreen  x" + pxy[0] + " y " + pxy[1]);
            x = pxy[0] + 3;
            y = pxy[1] + 3;
        } else {
            x = r.left + view.getWidth() / 2;
            y = r.top + view.getHeight() / 2;
        }

        long downTime = SystemClock.uptimeMillis();
        final MotionEvent downEvent = MotionEvent.obtain(downTime, downTime,
                MotionEvent.ACTION_DOWN, x, y, 0);
        pressDownTime = downTime;
//        downTime += 1000;
//        final MotionEvent upEvent = MotionEvent.obtain(downTime, downTime,
//                MotionEvent.ACTION_UP, x, y, 0);
        View topView = HookWindowManagerGlobal.getInstance().getTopView();
        if (null == topView) {
            LogManager.getInstance().logInfo("setSimulateViewPressDown get topview is null");
            return false;
        } else {
            LogManager.getInstance().logInfo("setSimulateViewPressDown topView = " + topView.getContext().toString());
        }

        boolean down = topView.dispatchTouchEvent(downEvent);
//        boolean up = topView.dispatchTouchEvent(upEvent);

        downEvent.recycle();
//        upEvent.recycle();

        LogManager.getInstance().logInfo("setSimulateViewPressDown topView = pressDownTime = " + pressDownTime);

        LogManager.getInstance().logError("setSimulateViewPressDown down = " + down + "  x  =  " + x + "  y  " + y);
        return down;
    }


    public static boolean setSimulateViewPressUp(View view) {
        Rect r = new Rect();
        view.getGlobalVisibleRect(r);
        int x;
        int y;
        if (r.top == 0 && r.bottom == 0 && r.left == 0 && r.right == 0) {
            int[] pxy = new int[2];
            view.getLocationOnScreen(pxy);
            LogManager.getInstance().logInfo("getLocationOnScreen  x" + pxy[0] + " y " + pxy[1]);
            x = pxy[0] + 3;
            y = pxy[1] + 3;
        } else {
            x = r.left + view.getWidth() / 2;
            y = r.top + view.getHeight() / 2;
        }

        long downTime = SystemClock.uptimeMillis();
//        final MotionEvent downEvent = MotionEvent.obtain(downTime, downTime,
//                MotionEvent.ACTION_DOWN, x, y, 0);
//        downTime += 1000;
        final MotionEvent upEvent = MotionEvent.obtain(pressDownTime, downTime,
                MotionEvent.ACTION_UP, x, y, 0);
        View topView = HookWindowManagerGlobal.getInstance().getTopView();
        if (null == topView) {
            LogManager.getInstance().logInfo("setSimulateViewPressUp get topview is null");
            return false;
        } else {
            LogManager.getInstance().logInfo("setSimulateViewPressUp topView = " + topView.getContext().toString());
        }

//        boolean down = topView.dispatchTouchEvent(downEvent);
        boolean up = topView.dispatchTouchEvent(upEvent);

//        downEvent.recycle();
        upEvent.recycle();


        LogManager.getInstance().logInfo("setSimulateViewPressUp topView = pressDownTime = " + pressDownTime);

        LogManager.getInstance().logError("setSimulateViewPressUp up = " + up + "  x  =  " + x + "  y  " + y);
        return up;
    }
}
